package com.ktwlsoft.archivemanage.service.utils;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * zip工具类
 *
 * @author zhuhe on 2019/6/17 11:32
 * @version 1.0
 */
public class ZipUtils {

    /** 日志对象 **/
    private static Logger logger = LoggerFactory.getLogger(ZipUtils.class);

    /**
      * 生成压缩文件 on 2019/6/17 11:36
      *
      * @param srcFiles 要压缩的文件集合
      * @param zipPath 压缩文件路径
      * @param path 压缩包下文件夹,为null时所有文件在同一文件夹下,否则已path为更目录进行文件夹及文件迭代
      * @return String
      */
    public static String zipFiles(File[] srcFiles, String zipPath,String path) {
        File zipFile = createNewFile(zipPath);
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;
        // 创建 ZipOutputStream
        ZipOutputStream zipOutputStream = null;
        // 创建 FileInputStream 对象
        FileInputStream fileInputStream = null;
        try {
            // 实例化 FileOutputStream 对象
            fileOutputStream = new FileOutputStream(zipFile);
            // 实例化 ZipOutputStream 对象
            zipOutputStream = new ZipOutputStream(fileOutputStream);
            // 创建 ZipEntry 对象
            ZipEntry zipEntry = null;
            // 遍历源文件数组
            List<File> files = getAllFile(srcFiles, Lists.newArrayList());
            for (int i = 0; i < files.size(); i++) {
                // 将源文件数组中的当前文件读入 FileInputStream 流中
                try {
                    fileInputStream = new FileInputStream(files.get(i));
                    // 实例化 ZipEntry 对象，源文件数组中的当前文件
                    if(path != null && !"".equals(path.trim())) {
                        String newPath = "";
                        String filePath = files.get(i).getPath();
                        filePath = filePath.substring(filePath.lastIndexOf(path) + (path.length() + 1),filePath.length());
                        if(!"".equals(filePath)) {
                            newPath = filePath;
                        }else{
                            newPath = "";
                        }
                        zipEntry = new ZipEntry(path + File.separator + newPath);
                    }else{
                        int i1 = 0;
                        String fileName = files.get(i).getName();
                        for(int j = 0;j <= i;j++){
                            if(j != i && fileName.equals(files.get(j).getName())){
                                i1++;
                            }
                        }
                        if(i1 != 0){
                            fileName = fileName.substring(0,fileName.lastIndexOf(".")) + "(" + i1 + ")" + fileName.substring(fileName.lastIndexOf("."));
                        }
                        zipEntry = new ZipEntry(URLDecoder.decode(fileName,"UTF-8"));
                    }
                    zipOutputStream.putNextEntry(zipEntry);
                    // 该变量记录每次真正读的字节个数
                    int len;
                    // 定义每次读取的字节数组
                    byte[] buffer = new byte[1024];
                    while ((len = fileInputStream.read(buffer)) > 0) {
                        zipOutputStream.write(buffer, 0, len);
                    }
                }catch (IOException e){
                    logger.error(e.getMessage());
                }finally {
                    if(fileInputStream != null){
                        fileInputStream.close();
                    }
                }
            }
        } catch (IOException e) {
            logger.error(e.getMessage());
        }finally {
            closeIO(fileOutputStream,zipOutputStream,fileInputStream);
        }
        return zipPath;
    }

    /**
      * 关闭流 on 2019/6/18 9:53
      *
      * @param fileOutputStream fileOutputStream
      * @param zipOutputStream zipOutputStream
      * @param fileInputStream fileInputStream
      */
    private static void closeIO(FileOutputStream fileOutputStream,ZipOutputStream zipOutputStream,FileInputStream fileInputStream){
        try {
            if(zipOutputStream != null) {
                zipOutputStream.closeEntry();
                zipOutputStream.close();
            }
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if(fileOutputStream != null) {
                fileOutputStream.close();
            }
        }catch (IOException e){
            logger.error(e.getMessage());
        }
    }

    /**
      * 创建zip文件 on 2019/6/18 9:43
      *
      * @param zipPath zipPath
      */
    private static File createNewFile(String zipPath){
        File zipFile = new File(zipPath);
        // 判断压缩后的文件存在不，不存在则创建
        if (!zipFile.exists()) {
            try {
                if(!zipFile.createNewFile()){
                    logger.error("zip文件创建失败");
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        return zipFile;
    }

    /**
      * 获取所有文件 on 2020/1/14 17:54
      *
      * @param srcFiles srcFiles
      * @param files files
      * @return List<File>
      */
    public static List<File> getAllFile(File[] srcFiles,List<File> files){
        if(srcFiles == null || srcFiles.length <= 0){
            return files;
        }
        if(files == null){
            return Lists.newArrayList();
        }
        for(File file:srcFiles){
            if(file != null) {
                if (file.isFile()) {
                    files.add(file);
                } else {
                    getAllFile(file.listFiles(), files);
                }
            }
        }
        return files;
    }
}